/*
 * 键盘
 * 舞者无罪
 * 2014.12.01
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include "lang.h"
#include "resource.h"
#include "func.h"
#include "com.h"
#include "mhbtn.h"
#include "mhlabel.h"
#include "mhedit.h"
#include "keypane.h"
#include "mhedit.h"


/*
 *
 */
static void CreateKeypaneInterface(HWND hWnd)
{
    int i = 0, j = 0;
    for(i = 0; i < 2; ++i)
    {
        for(j = 0; j < 5; ++j)
        {
            CreateWindow(MH_STATIC_NAME,
                "",
                WS_CHILD | WS_VISIBLE,
                ID_0NUM + i * 5 + j,
                8 + (CX_BIG_NUM_BMP + 3) * j,
                8 + (CY_BIG_NUM_BMP + 3) * i,
                CX_BIG_NUM_BMP,
                CY_BIG_NUM_BMP,
                hWnd, (int)&g_bmp[BMP_0BIG + i * 5 + j]);
        }
    }
    CreateWindow(MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_ESC,
        8,
        8 + (CY_BIG_NUM_BMP + 3) * 2 + 2,
        CX_ESC_BMP,
        CY_BIG_NUM_BMP,
        hWnd, (int)&g_bmp[BMP_ESC]);
    CreateWindow(MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_DEL,
        8 + (CX_ESC_BMP + 3),
        8 + (CY_BIG_NUM_BMP + 3) * 2 + 2,
        CX_DEL_BMP,
        CY_BIG_NUM_BMP,
        hWnd, (int)&g_bmp[BMP_DEL]);
    CreateWindow(MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_ENTER,
        8 + (CX_ESC_BMP + 3) + (CX_DEL_BMP + 3),
        8 + (CY_BIG_NUM_BMP + 3) * 2 + 2,
        CX_ENTER_BMP,
        CY_BIG_NUM_BMP,
        hWnd, (int)&g_bmp[BMP_ENTER]);
    CreateWindow(MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_MOVE,
        14 + (CX_BIG_NUM_BMP + 3) * 5,
        8,
        CX_MOVE_BMP,
        CY_MOVE_BMP,
        hWnd, (int)&g_bmp[BMP_MOVE]);
}
/*
 *
 */
static void OnChar(HWND hWnd, int ch)
{
    if(ch >= '0' && ch <= '9')
    {
        HWND hParent = GetHosting(hWnd);
        WND_EXTRA_DATA data;
        data.value = GetWindowAdditionalData(hWnd);
        HWND hEditWnd = GetFocusChild(hParent);
        if(hParent > 0 && data.pwnd_keypane && hEditWnd > 0)
        {
            if(data.pwnd_keypane->min == data.pwnd_keypane->max)
            {
                switch(data.pwnd_keypane->min)
                {
                case KEYPANE_TYPE_TIME:
                    {
                        g_edit_text[g_edit_index] = ch;
                        ++g_edit_index;
                        if(!g_edit_text[g_edit_index])
                        {
                            g_edit_index = 0;
                        }
                        else if(!isdigit(g_edit_text[g_edit_index]))
                        {
                            ++g_edit_index;
                        }
                    }
                    break;
                case KEYPANE_TYPE_FILE:
                    {
                        int bValid = TRUE;
                        const char *psc = GetWindowCaption(hEditWnd);
                        if(data.pwnd_keypane->valid)
                        {
                            if(strlen(psc) > 7)
                            {
                                bValid = FALSE;
                            }
                        }
                        if(bValid)
                        {
                            if(data.pwnd_keypane->valid)
                            {
                                AddEditChar(hEditWnd, ch);
                            }
                            else
                            {
                                data.pwnd_keypane->valid = TRUE;
                                g_edit_index = -1;
                                char sc[2] = {0};
                                sc[0] = ch;
                                SetWindowCaption(hEditWnd, sc);
                                InvalidateRect(hEditWnd, 0, TRUE);
                            }
                        }
                    }
                    return;
                }
                SetWindowCaption(hEditWnd, g_edit_text);
                InvalidateRect(hEditWnd, 0, TRUE);
            }
            else
            {
                char sc[EDIT_MAX_LEN + 1] = {0};
                const char *p = GetWindowCaption(hEditWnd);
                int bInvalid = FALSE;
                if(1)
                {
                    char sc[128] = {0, 0};
                    if(data.pwnd_keypane->valid)
                    {
                        strcat(sc, GetWindowCaption(hEditWnd));
                        int len = strlen(sc);
                        sc[len] = ch;
                        sc[len + 1] = 0;
                    }
                    else
                    {
                        sc[0] = ch;
                    }
                    int value = atoi(sc);
                    if(value < data.pwnd_keypane->min || value > data.pwnd_keypane->max)
                    {
                        bInvalid = TRUE;
                    }
                }
                if(bInvalid)
                {
                    //
                }
                else if(data.pwnd_keypane->valid)
                {
                    AddEditChar(hEditWnd, ch);
                }
                else
                {
                    if(p && !data.pwnd_keypane->err)
                    {
                        data.pwnd_keypane->value = atoi(p);
                    }
                    data.pwnd_keypane->valid = TRUE;
                    g_edit_index = -1;
                    sc[0] = ch;
                    SetWindowCaption(hEditWnd, sc);
                    InvalidateRect(hEditWnd, 0, TRUE);
                }
            }
        }
    }
}
/*
 *
 */
static void OnBtnCmd(HWND hWnd, int nID)
{
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    switch(nID)
    {
    case ID_0NUM:
        {
            OnChar(hWnd, '0');
        }
        break;
    case ID_1NUM:
        {
            OnChar(hWnd, '1');
        }
        break;
    case ID_2NUM:
        {
            OnChar(hWnd, '2');
        }
        break;
    case ID_3NUM:
        {
            OnChar(hWnd, '3');
        }
        break;
    case ID_4NUM:
        {
            OnChar(hWnd, '4');
        }
        break;
    case ID_5NUM:
        {
            OnChar(hWnd, '5');
        }
        break;
    case ID_6NUM:
        {
            OnChar(hWnd, '6');
        }
        break;
    case ID_7NUM:
        {
            OnChar(hWnd, '7');
        }
        break;
    case ID_8NUM:
        {
            OnChar(hWnd, '8');
        }
        break;
    case ID_9NUM:
        {
            OnChar(hWnd, '9');
        }
        break;
    case ID_ESC:
        {
            g_edit_index = 0;
            HWND hParent = GetHosting(hWnd);
            WND_EXTRA_DATA data;
            data.value = GetWindowAdditionalData(hWnd);
            if(hParent > 0 && data.pwnd_keypane)
            {
                if(data.pwnd_keypane->min == data.pwnd_keypane->max)
                {
                    SendMessage(hParent, MSG_KEYPANE_ESC, 0, 0);
                }
                else
                {
                    HWND hEditWnd = GetFocusChild(hParent);
                    if(hEditWnd > 0)
                    {
                        SetEditActive(hEditWnd, FALSE);
                        char sc[32] = { 0 };
                        sprintf(sc, "%d", data.pwnd_keypane->value);
                        SetWindowCaption(hEditWnd, sc);
                    }
                }
            }
            PostMessage(hWnd, MSG_CLOSE, 0, 0);
        }
        break;
    case ID_ENTER:
        {
            g_edit_index = 0;
            HWND hParent = GetHosting(hWnd);
            int ret = 0;
            if(hParent > 0)
            {
                HWND hEditWnd = GetFocusChild(hParent);
                if(hEditWnd > 0)
                {
                    ret = SendMessage(hParent, MSG_SETDATA, GetDlgCtrlID(hEditWnd), 0);
                    if(ret)
                    {
                        SetEditVirtual(hEditWnd, TRUE);
                        WND_EXTRA_DATA data;
                        data.value = GetWindowAdditionalData(hWnd);
                        if(data.pwnd_keypane)
                        {
                            data.pwnd_keypane->err = TRUE;
                            data.pwnd_keypane->valid = FALSE;
                        }
                    }
                    else
                    {
                        SetEditActive(hEditWnd, FALSE);
                    }
                }
            }
            if(!ret)
            {
                PostMessage(hWnd, MSG_CLOSE, 0, 0);
            }
        }
        break;
    case ID_DEL:
        {
            HWND hParent = GetHosting(hWnd);
            if(hParent > 0)
            {
                HWND hEditWnd = GetFocusChild(hParent);
                if(hEditWnd > 0)
                {
                    const char *p = GetWindowCaption(hEditWnd);
                    PKEYPANE_DATA pkey = (PKEYPANE_DATA)GetWindowAdditionalData(hWnd);
                    if(pkey && !pkey->valid)
                    {
                        if(p)
                        {
                            pkey->value = atoi(p);
                        }
                        pkey->valid = TRUE;
                        SetWindowCaption(hEditWnd, "");
                        InvalidateRect(hEditWnd, 0, TRUE);
                    }
                    else if(p);
                    {
                        DecEditChar(hEditWnd);
                    }
                }
            }
        }
        break;
    case ID_LEFT:
        {
            SendMessage(GetHosting(hWnd), MSG_LEFT, 0, 0);
        }
        break;
    case ID_RGHT:
        {
            SendMessage(GetHosting(hWnd), MSG_RIGHT, 0, 0);
        }
        break;
    case ID_DOWN:
        if(data.pwnd_keypane)
        {
            if(data.pwnd_keypane->min < data.pwnd_keypane->max)
            {
                HWND hParent = GetHosting(hWnd);
                if(hParent > 0)
                {
                    HWND hTmp = GetFocusChild(hParent);
                    if(hTmp > 0)
                    {
                        const char *sc = GetWindowCaption(hTmp);
                        int n = atoi(sc);
                        if(n > data.pwnd_keypane->min)
                        {
                            --n;
                            char str[64] = { 0 };
                            sprintf(str, "%d", n);
                            SetWindowCaption(hTmp, str);
                            InvalidateRect(hTmp, 0, TRUE);
                            data.pwnd_keypane->valid = TRUE;
                        }
                    }
                }
            }
        }
        break;
    case ID_UP:
        if(data.pwnd_keypane)
        {
            if(data.pwnd_keypane->min < data.pwnd_keypane->max)
            {
                HWND hParent = GetHosting(hWnd);
                if(hParent > 0)
                {
                    HWND hTmp = GetFocusChild(hParent);
                    if(hTmp > 0)
                    {
                        const char *sc = GetWindowCaption(hTmp);
                        int n = atoi(sc);
                        if(n < data.pwnd_keypane->max)
                        {
                            ++n;
                            char str[64] = { 0 };
                            sprintf(str, "%d", n);
                            SetWindowCaption(hTmp, str);
                            InvalidateRect(hTmp, 0, TRUE);
                            data.pwnd_keypane->valid = TRUE;
                        }
                    }
                }
            }
        }
        break;
    }
}
/*
 *
 */
static void OnKeyDown(HWND hWnd, uint key)
{
    if(key == SCANCODE_ENTER)
    {
        OnBtnCmd(hWnd, ID_ENTER);
    }
    else if(key == SCANCODE_ESCAPE)
    {
        OnBtnCmd(hWnd, ID_ESC);
    }
    else if(key == SCANCODE_REMOVE || key == SCANCODE_BACKSPACE)
    {
        OnBtnCmd(hWnd, ID_DEL);
    }
    else if(key == SCANCODE_MINUS_USER)
    {
        WND_EXTRA_DATA data;
        data.value = GetWindowAdditionalData(hWnd);
        HWND hParent = GetHosting(hWnd);
        HWND hEditWnd = GetFocusChild(hParent);
        if(data.pwnd_keypane && hEditWnd > 0)
        {
            if(data.pwnd_keypane->min < data.pwnd_keypane->max)
            {
                BOOL bValid = FALSE;
                if(data.pwnd_keypane->valid)
                {
                    if(!atoi(GetWindowCaption(hEditWnd)))
                    {
                        bValid = TRUE;
                    }
                }
                else
                {
                    data.pwnd_keypane->valid = TRUE;
                    bValid = TRUE;
                }
                char sc[2] = { 0 };
                sc[0] = '-';
                SetWindowCaption(hEditWnd, sc);
                InvalidateRect(hEditWnd, 0, TRUE);
            }
        }
    }
    else if(key == SCANCODE_CURSORBLOCKLEFT)
    {
        OnBtnCmd(hWnd, ID_LEFT);
    }
    else if(key == SCANCODE_CURSORBLOCKRIGHT)
    {
        OnBtnCmd(hWnd, ID_RGHT);
    }
    else if(key == SCANCODE_CURSORBLOCKUP)
    {
        OnBtnCmd(hWnd, ID_UP);
    }
    else if(key == SCANCODE_CURSORBLOCKDOWN)
    {
        OnBtnCmd(hWnd, ID_DOWN);
    }
}
/*
 *
 */
static void OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    int x = lParam & 0xFFFF;
    int y = lParam >> 16;
    HWND hTmp = GetDlgItem(hWnd, ID_MOVE);
    RECT rect;
    GetClientRect(hTmp, &rect);
    ClientToScreen(hTmp, &rect.left, &rect.top);
    ClientToScreen(hTmp, &rect.right, &rect.bottom);
    ClientToScreen(hWnd, &x, &y);
    if(PtInRect(&rect, x, y))
    {
        ushort nID = 0;
        x -= rect.left;
        y -= rect.top;
        y = CY_MOVE_BMP - 1 - y;
        if(x > y)
        {
            if(CX_MOVE_BMP - x > y)
            {
                nID = ID_DOWN;
            }
            else
            {
                nID = ID_RGHT;
            }
        }
        else
        {
            if(CX_MOVE_BMP - x > y)
            {
                nID = ID_LEFT;
            }
            else
            {
                nID = ID_UP;
            }
        }
        OnBtnCmd(hWnd, nID);
    }
}
/*
 *
 */
static int KeypaneWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case MSG_CREATE:
        {
            g_edit_index = -2;
            WND_EXTRA_DATA data;
            data.value = GetWindowAdditionalData(hWnd);
            if(data.pwnd_keypane)
            {
                if(data.pwnd_keypane->min == data.pwnd_keypane->max)
                {
                    g_edit_index = 0;
                }
            }
            CreateKeypaneInterface(hWnd);
        }
        break;
    case MSG_PAINT:
        {
        }
        break;
    case MSG_CLOSE:
        {
            HWND hHosting = GetHosting(hWnd);
            if(hHosting)
            {
                EnableWindow(hHosting, TRUE);
            }
            DestroyMainWindow(hWnd);
            MainWindowCleanup (hWnd);
            if(hHosting)
            {
                HWND hEditWnd = GetFocusChild(hHosting);
                if(hEditWnd > 0)
                {
                    SetEditActive(hEditWnd, FALSE);
                    InvalidateRect(hEditWnd, NULL, TRUE);
                }
                PostMessage(hHosting, MSG_KEYPANECLOSE, 0, 0);
            }
        }
        return 0;
    case MSG_KEYDOWN:
        {
            OnKeyDown(hWnd, wParam);
        }
        return 0;
    case MSG_CHAR:
        {
            OnChar(hWnd, wParam);
        }
        return 0;
    case MSG_COMMAND:
        {
            OnBtnCmd(hWnd, LOWORD(wParam));
        }
        return 0;
    case MSG_DESTROY:
        {
            PKEYPANE_DATA pkey = (PKEYPANE_DATA)GetWindowAdditionalData(hWnd);
            if(pkey)
            {
                free(pkey);
                SetWindowAdditionalData(hWnd, 0);
            }
            ShowWindow(hWnd, SW_HIDE);
            DestroyAllControls (hWnd);
        }
        break;
    case MSG_ERASEBKGND:
        {
            DrawBitmapBkGnd(hWnd, (RECT*)lParam, &g_bmp[BMP_KEYPANE]);
        }
        return 0;
    case MSG_LBUTTONDOWN:
        {
            OnLButtonDown(hWnd, wParam, lParam);
        }
        break;
    }
    return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/*
 *
 */
HWND CreateKeyboardWindow(HWND hHosting, RECT rect, int min, int max, int value)
{
    HWND hWnd;
    MAINWINCREATE CreateInfo;

    int cx = CX_KEYPANE_BMP;
    int cy = CY_KEYPANE_BMP;

    WND_EXTRA_DATA data;
    data.pwnd_keypane = calloc(1, sizeof(WND_KEYPANE));
    data.pwnd_keypane->max = max;
    data.pwnd_keypane->min = min;
    data.pwnd_keypane->value = value;
    int x = rect.left + 10;
    if(rect.left + 15 + cx > CX_SCREEN)
    {
        x = __max(10, rect.left - 10 - cx);
    }
    int y = rect.bottom + 10;
    if(rect.bottom + 15 + cy > CY_SCREEN)
    {
        y = __max(10, rect.top - 10 - cy);
    }
    CreateInfo.dwStyle = WS_VISIBLE | WS_CHILD;
    CreateInfo.dwExStyle = WS_EX_NONE;
    CreateInfo.spCaption = "";
    CreateInfo.hMenu = 0;
    CreateInfo.hCursor = GetSystemCursor(0);
    CreateInfo.hIcon = 0;
    CreateInfo.MainWindowProc = KeypaneWinProc;
    CreateInfo.lx = x;
    CreateInfo.ty = y;
    CreateInfo.rx = x + cx;
    CreateInfo.by = y + cy;
    CreateInfo.iBkColor = COLOR_lightwhite;
    CreateInfo.dwAddData = data.value;
    CreateInfo.hHosting = hHosting;
    hWnd = CreateMainWindow(&CreateInfo);
    if(hWnd != HWND_INVALID)
    {
        HWND hEditWnd = GetFocusChild(hHosting);
        if(hEditWnd > 0)
        {
            SetEditActive(hEditWnd, TRUE);
        }
        EnableWindow(hHosting, FALSE);
        ShowWindow(hWnd, SW_SHOWNORMAL);
    }
    return hWnd;
}
